package com.bruce.tool.pay.alipay.wap.back;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alipay.easysdk.factory.Factory;
import com.alipay.easysdk.kernel.Config;
import com.alipay.easysdk.kernel.util.ResponseChecker;
import com.alipay.easysdk.payment.common.models.AlipayTradeQueryResponse;
import com.alipay.easysdk.payment.wap.Client;
import com.alipay.easysdk.payment.wap.models.AlipayTradeWapPayResponse;
import com.bruce.tool.common.exception.BaseRuntimeException;
import com.bruce.tool.common.exception.ErrorCode;
import com.bruce.tool.common.util.valid.ValidUtils;
import com.bruce.tool.pay.alipay.enums.AliPayTradeStatus;
import com.bruce.tool.pay.alipay.wap.to.WapOrderAliTo;
import com.bruce.tool.pay.alipay.wap.to.WapPayAliTo;
import com.bruce.tool.rpc.http.core.Https;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;

/**
 * 预订单信息拼接工具类
 * 0.定义通用化参数
 * 1.完成参数签名
 * 2.完成参数拼接
 * 新版支付宝接口地址:
 * wiki: https://opendocs.alipay.com/open/00y8k9
 *
 * @author Bruce(刘正航)
 */
@Slf4j
public class AliWapPayHelper {

    /**
     * 初始化支付配合着
     */
    public static void init(String appId, String primaryKey, String publicKey, String notifyUrl) {
        // 1. 设置参数（全局只需设置一次）
        Factory.setOptions(getOptions(appId, primaryKey, publicKey, notifyUrl));
    }

    /**
     * wap预订单信息拼接
     * wiki: https://opendocs.alipay.com/apis/api_1/alipay.trade.wap.pay
     */
    public static String joinPrePayInfo(WapPayAliTo wapPayAliTo) {
        ValidUtils.fastValid(wapPayAliTo);
        AlipayTradeWapPayResponse response;
        try {
            // 2. 发起API调用
            Client client = Factory.Payment.Wap();
            if (StringUtils.isNotBlank(wapPayAliTo.getPassback())) {
                client.optional("passback_params", Https.urlEncode(wapPayAliTo.getPassback()));
            }
            response = client.pay(wapPayAliTo.getSubject(),
                    wapPayAliTo.getOrderNo(),
                    wapPayAliTo.getTotalAmount(),
                    wapPayAliTo.getQuitUrl(),
                    wapPayAliTo.getReturnUrl());
        } catch (Exception e) {
            log.error("支付宝发起网页支付异常", e);
            throw new BaseRuntimeException(ErrorCode.SYSTEM_ERROR, "支付宝发起网页支付异常:" + e.getMessage());
        }
        // 3. 处理响应或异常
        // 3. 处理响应或异常
        if (!ResponseChecker.success(response)) {
            throw new BaseRuntimeException(ErrorCode.SYSTEM_ERROR, "支付宝发起网页支付异常:" + response.body);
        }
        return response.body;
    }

    /**
     * 获取订单信息
     * wiki: https://opendocs.alipay.com/apis/api_1/alipay.trade.query
     */
    public static String wapOrderInfo(WapOrderAliTo wapOrderAliTo) {
        ValidUtils.fastValid(wapOrderAliTo);
        AlipayTradeQueryResponse response;
        try {
            response = Factory.Payment.Common().query(wapOrderAliTo.getOrderNo());
        } catch (Exception e) {
            log.error("获取订单信息错误", e);
            throw new BaseRuntimeException(ErrorCode.SYSTEM_ERROR, e.getMessage());
        }
        if (!ResponseChecker.success(response)) {
            throw new BaseRuntimeException(ErrorCode.SYSTEM_ERROR, "支付宝订单查询失败:" + response.subMsg);
        }
        String result = response.body;
        JSONObject jsonObject = JSON.parseObject(result);
        JSONObject jsonResponse = jsonObject.getJSONObject("alipay_trade_query_response");
        String tradeStatusAli = jsonResponse.getString("trade_status");
        if (StringUtils.isBlank(tradeStatusAli)) {
            throw new BaseRuntimeException(ErrorCode.SYSTEM_ERROR, "支付宝订单状态:" + jsonResponse.getString("sub_msg"));
        }
        AliPayTradeStatus tradeStatus = AliPayTradeStatus.valueOf(tradeStatusAli);
        if (!AliPayTradeStatus.TRADE_SUCCESS.equals(tradeStatus)) {
            throw new BaseRuntimeException(ErrorCode.SYSTEM_ERROR, "支付宝订单状态:" + tradeStatus.getValue());
        }
        return result;
    }

    private static Config getOptions(String appId, String primaryKey, String publicKey, String notifyUrl) {
        Config config = new Config();
        config.protocol = "https";
        config.gatewayHost = "openapi.alipay.com";
        config.signType = "RSA2";

        // <-- 请填写您的AppId，例如：2019091767145019 -->
        config.appId = appId;

        // 为避免私钥随源码泄露，推荐从文件中读取私钥字符串而不是写入源码中
        // <-- 请填写您的应用私钥，例如：MIIEvQIBADANB ... ... -->
        config.merchantPrivateKey = primaryKey;

        //注：如果采用非证书模式，则无需赋值上面的三个证书路径，改为赋值如下的支付宝公钥字符串即可
        // <-- 请填写您的支付宝公钥，例如：MIIBIjANBg... -->
        config.alipayPublicKey = publicKey;

        //可设置异步通知接收服务地址（可选）
        config.notifyUrl = notifyUrl;

        return config;
    }

    public static void main(String[] args) {
        AliWapPayHelper.init("", "", "", "");
        WapPayAliTo ali = JSON.parseObject("{\n" +
                "\t\"subject\":\"测试支付宝-网页支付\",\n" +
                "\t\"totalAmount\":\"0.01\",\n" +
                "\t\"quitUrl\":\"http://www.baidu.com\",\n" +
                "\t\"returnUrl\":\"http://www.baidu.com\",\n" +
                "\t\"orderNo\":\"12809328138\",\n" +
                "\t\"passbackParams\":\"a=1&b=2\"\n" +
                "}", WapPayAliTo.class);
        System.out.println(AliWapPayHelper.joinPrePayInfo(ali));
    }
}
